import java.util.Scanner;


public class OSSimulation 
{
	public static void main(String[] args) throws InterruptedException
	{
		int IO_processes = 0;
		int CP_processes = 0;
		int PC_processes = 0;
		
		int scheduling_policy = 0; //default 0 which is round-robin
		
		System.out.println("Welcome to the TCSS 422 OS Simulator!");
		System.out.println("Created by: Sagar Kamboj, Sanjeev Kamboj, Adson Vieira da Silva, and Pak Liu");
		
		Scanner s = new Scanner(System.in);
		
		System.out.println();
		System.out.println();
		
		System.out.print("Enter the number of I/0 processes (minimum 2): ");
		IO_processes = s.nextInt();
		
		while(IO_processes <= 1)
		{
			System.out.println("invalid # of processes. Need at least 2!");
			System.out.print("Enter the number of I/0 processes (minimum 2): ");
			IO_processes = s.nextInt();
			
		}
		
		System.out.println();
		
		
		System.out.print("Enter the number of Producer/Consumer processes (minimum 1 pair): ");
		PC_processes = s.nextInt();
		
		while(PC_processes <= 0)
		{
			System.out.println("invalid # of processes. Need at least 1!");
			System.out.print("Enter the number of Producer/Consumer processes (minimum 1 pair): ");
			PC_processes = s.nextInt();
		}
		
		System.out.println();
		
		
		System.out.print("Enter the number of Compute Bound processes (minimum 1 pair): ");
		CP_processes = s.nextInt();
		
		while(CP_processes <= 0)
		{
			System.out.println("invalid # of processes. Need at least 1!");
			System.out.print("Enter the number of Compute Bound processes (minimum 1 pair): ");
			CP_processes = s.nextInt();
		}
		
		System.out.println();
		
		System.out.print("Enter the scheduling policy wanted (0 = round-robin, 1 = lottery, 2 = priority): ");
		scheduling_policy = s.nextInt();
		
		while(scheduling_policy < -1 || scheduling_policy > 3)
		{
			System.out.println("invalid policy chosen. Please try again! ");
			System.out.print("Enter the scheduling policy wanted (0 = round-robin, 1 = lottery, 2 = priority): ");
			scheduling_policy = s.nextInt();
		}
		
		System.out.println();
		
		/////////////////////////////////// end of user input
		
		PCBList my_list = new PCBList(IO_processes, CP_processes, PC_processes);
		
		Memory mem = new Memory();
		
		Scheduler my_scheduler = new Scheduler(my_list, scheduling_policy);
		
		CPU my_cpu = new CPU(my_list, my_scheduler, mem);
		
		SysTimer timer = new SysTimer(my_cpu, my_scheduler, 50); // 50ms
		
		//Need to make the timer
		
		IODevice my_IODevice1 = new IODevice(my_cpu, IODevice.DeviceType.DISK);
		IODevice my_IODevice2 = new IODevice(my_cpu, IODevice.DeviceType.KEYBOARD);
	
		
		//sends io devices to cpu
		my_cpu.makeIODevice(my_IODevice1);
		my_cpu.makeIODevice(my_IODevice2);

		
		// might need to make cpu extend thread if this doesnt work
		
		Thread cpu = new Thread(my_cpu);
		Thread timer_t = new Thread(timer);
		cpu.start();
		timer_t.start();
		my_IODevice1.start();
		my_IODevice2.start();
		
		cpu.join();
		my_IODevice1.join();
        my_IODevice2.join();
        timer_t.join();   
		
	}

}
